#pragma once
#include <list>
#include <map>
#include "util/Singleton.h"
#include "Types.h"
#include "rendering/Scene.h"
#include "physics/IPhysics.h"
#include "Input.h"




namespace Boon
{
	class Messenger;

class BOON_API ProcessManager : public Singleton<ProcessManager>
{
	SINGLETON(ProcessManager)

	typedef std::list<GameObjectWeak>						ListGameObjectDirty;


	virtual void	OnInitialize();
	virtual void	OnDestroy();
public:

	/*! \brief		Call this Function to call one iteration of the
	 				GameObject/GameComponent life cycle
	*/
	void			ProcessUpdate();

	/*! \brief		Call this Function to call one iteration of the Scene-Graph-Render loop
					Note: This routine can be skipped if Timer is set to draw on certain FPS
	*/
	void			ProcessRendering();

	/*! \brief		Call this Function to call one iteration of the Physics-Update loop
					Note: This routine can be skipped if Timer is set iterate on certain FPS
	*/
	void			ProcessPhysics();

	/*! \brief		Destroys a GameObject
		\param		id - The unique Object-ID of a GameObject
	*/
	void			DestroyGameObject( const GameObjectID id );

	//////////////////////////////////////////////////////////////////////////
	// Temporary, will be removed
	Rendering::ISceneNodeStrong	GetRootNode()
	{
		return m_Scene->m_Root;
	}

	Rendering::ISceneNodeStrong		GetSceneNode( GameObjectID id )
	{
		return m_Scene->GetNode( id );
	}
	//////////////////////////////////////////////////////////////////////////
private:
	/*! \brief		Will be called on event: Event_GameObject_Created
	\param		g - Strong-Reference to a event
	*/
	void			OnGameObjectDirty( const IMessengerEventStrong& e );


	ListGameObjectDirty				m_GameObjectsDirty; 		/*!< List containint all Gameobjects who previously created a GameComponent and need to call ProcessDirty() */
	Shared_ptr<Rendering::Scene>	m_Scene;					/*!< Object responsible for rendering all render-components */
	Shared_ptr<Physics::IPhysics>	m_Physics;					/*!< Object holding and controlling physics world */
	Messenger*						m_Messenger;				/*!< Reference to messaging object for sending event through engine */
	Input*							m_Input;					/*!< Reference to input manager singleton responsible for updating registered commands */
};

}
